// Copyright (c) Microsoft Corporation.  All rights reserved.
#pragma once

namespace  Microsoft { namespace WindowsAPICodePack { namespace DirectX {

/// <summary>
/// Supports an indexer object
/// </summary>
public ref struct Indexer
{
protected:
    void CheckRange(int i)
    {
        if (i < 0 || i >=  maxIndex)
        {
            throw gcnew IndexOutOfRangeException(
                String::Format("Range is 0 to {0}", maxIndex));
        }
    }
public:
    property int MaximumIndex
    {
        int get() { return maxIndex; }
    }

public protected:
    Indexer(int len) : maxIndex(len) { }

private:
    int maxIndex;
};

/// <summary>
/// Supports a Byte indexer object
/// </summary>
public ref struct ByteIndexer : Indexer
{
public:
    property Byte default[int] 
    {
        Byte get(int i)
        {
            CheckRange(i);
            return nativeArray[i];
        }

        void set(int i, Byte value)
        {
            CheckRange(i);
            nativeArray[i] = value;
        }   
    }

public protected:
    ByteIndexer(int len, UINT8* arr) : Indexer(len), nativeArray(arr) { }

private:
    UINT8* nativeArray;
};

/// <summary>
/// Supports a Boolean indexer object
/// </summary>
public ref struct BoolIndexer : Indexer
{
public:
    property Boolean default[int] 
    {
        Boolean get(int i)
        {
            CheckRange(i);
            return nativeArray[i] != 0;
        }

        void set(int i, Boolean value)
        {
            CheckRange(i);
            nativeArray[i] = static_cast<BOOL>(value);
        }   
    }

public protected:
    BoolIndexer(int len, BOOL* arr) : Indexer(len), nativeArray(arr) { }

private:
    BOOL* nativeArray;
};
} } }
